#include "zookeeperutil.h"

#include <iostream>
#include <semaphore.h>
#include "mprpcapplication.h"

ZkClient::ZkClient():m_zhandle(nullptr){}

ZkClient::~ZkClient()
{
    if(m_zhandle)
    {
        zookeeper_close(m_zhandle);
    }
}
void global_watcher(zhandle_t* zh,int type,int state,const char* path,void* watcherCtx)
{
    if(type==ZOO_SESSION_EVENT)
    {
        if(state==ZOO_CONNECTED_STATE)
        {
            sem_t *sem=(sem_t*)zoo_get_context(zh);
            sem_post(sem);
        }
        
    }
}
void ZkClient::start()
{
    std::string host=MrpcApplication::getInstance().getConfig().Load("zookeeperip");
    std::string port=MrpcApplication::getInstance().getConfig().Load("zookeeperport");
    std::string connstr=host+":"+port;

    m_zhandle=zookeeper_init(connstr.c_str(),global_watcher,3000,nullptr,nullptr,0);
    if(m_zhandle==nullptr)
    {
        std::cout<<"zookeeper init error\n";
        exit(EXIT_FAILURE);
    }
    sem_t sem;
    sem_init(&sem,0,0);
    zoo_set_context(m_zhandle,&sem);
    
    sem_wait(&sem);
    std::cout<<"zookeeper_init success\n";
}

void ZkClient::Create(const char* path,const char* data,int datalen,int state)
{
    char path_buffer[128]={0};
    int bufferlen=sizeof(path_buffer);
    int flag;
    flag=zoo_exists(m_zhandle,path,0,nullptr);
    if(ZNONODE==flag)
    {
        flag=zoo_create(m_zhandle,path,data,datalen,
                        &ZOO_OPEN_ACL_UNSAFE,state,path_buffer,bufferlen);
        if(flag==ZOK)
        {
            std::cout<<"znode create success....path: "<<path<<std::endl;
        }
        else
        {
            std::cout<<"flag: "<<flag<<std::endl;
            std::cout<<"znode create error...path:"<<path<<std::endl;
            exit(EXIT_FAILURE);
        }
    }
}

std::string ZkClient::GetData(const char* path)
{
    char buffer[64]={0};
    int bufferlen=sizeof(buffer);
    int flag=zoo_get(m_zhandle,path,0,buffer,&bufferlen,nullptr);
    if(flag!=ZOK)
    {
        std::cout<<"get znode error...path: "<<path<<std::endl;
        return "";
    }
    return buffer;
}